home *** CD-ROM | disk | FTP | other *** search
/ PC/CD Gamer UK 120 / CD Gamer Issue 120 (March 2003) (Disc 2).ISO / mods / Q2_Codered / codeRED1_0.exe / Data1.cab / cl_newfx.c < prev    next >
Encoding:
C/C++ Source or Header  |  2002-10-11  |  24.8 KB  |  1,270 lines

  1. /*
  2. Copyright (C) 1997-2001 Id Software, Inc.
  3.  
  4. This program is free software; you can redistribute it and/or
  5. modify it under the terms of the GNU General Public License
  6. as published by the Free Software Foundation; either version 2
  7. of the License, or (at your option) any later version.
  8.  
  9. This program is distributed in the hope that it will be useful,
  10. but WITHOUT ANY WARRANTY; without even the implied warranty of
  11. MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  
  12.  
  13. See the GNU General Public License for more details.
  14.  
  15. You should have received a copy of the GNU General Public License
  16. along with this program; if not, write to the Free Software
  17. Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
  18.  
  19. */
  20. // cl_newfx.c -- MORE entity effects parsing and management
  21.  
  22. #include "client.h"
  23.  
  24. extern cparticle_t    particles[MAX_PARTICLES];
  25. extern int            cl_numparticles;
  26. extern cvar_t        *vid_ref;
  27.  
  28. extern void MakeNormalVectors (vec3_t forward, vec3_t right, vec3_t up);
  29.  
  30. #ifdef _WIN32
  31. static __inline cparticle_t *new_particle (void)
  32. #else
  33. static inline cparticle_t *new_particle (void)
  34. #endif
  35. {
  36.     cparticle_t    *p;
  37.     extern cparticle_t    *active_particles, *free_particles;
  38.  
  39.     if (!free_particles)
  40.         return NULL;
  41.  
  42.     p = free_particles;
  43.     free_particles = p->next;
  44.     p->next = active_particles;
  45.     p->type = 0;
  46.     p->time = cl.time;
  47.  
  48.     return (active_particles = p);
  49. }
  50.  
  51. /*
  52. ======
  53. vectoangles2 - this is duplicated in the game DLL, but I need it here.
  54. ======
  55. */
  56. void vectoangles2 (vec3_t value1, vec3_t angles)
  57. {
  58.     float    forward;
  59.     float    yaw, pitch;
  60.     
  61.     if (value1[1] == 0 && value1[0] == 0)
  62.     {
  63.         yaw = 0;
  64.         if (value1[2] > 0)
  65.             pitch = 90;
  66.         else
  67.             pitch = 270;
  68.     }
  69.     else
  70.     {
  71.     // PMM - fixed to correct for pitch of 0
  72.         if (value1[0])
  73.             yaw = (atan2(value1[1], value1[0]) * 180 / M_PI);
  74.         else if (value1[1] > 0)
  75.             yaw = 90;
  76.         else
  77.             yaw = 270;
  78.  
  79.         if (yaw < 0)
  80.             yaw += 360;
  81.  
  82.         forward = sqrt (value1[0]*value1[0] + value1[1]*value1[1]);
  83.         pitch = (atan2(value1[2], forward) * 180 / M_PI);
  84.         if (pitch < 0)
  85.             pitch += 360;
  86.     }
  87.  
  88.     angles[PITCH] = -pitch;
  89.     angles[YAW] = yaw;
  90.     angles[ROLL] = 0;
  91. }
  92.  
  93. //=============
  94. //=============
  95. void CL_Flashlight (int ent, vec3_t pos)
  96. {
  97.     cdlight_t    *dl;
  98.  
  99.     dl = CL_AllocDlight (ent);
  100.     VectorCopy (pos,  dl->origin);
  101.     dl->radius = 400;
  102.     dl->minlight = 250;
  103.     dl->die = cl.time + 100;
  104.     dl->color[0] = 1;
  105.     dl->color[1] = 1;
  106.     dl->color[2] = 1;
  107. }
  108.  
  109. /*
  110. ======
  111. CL_ColorFlash - flash of light
  112. ======
  113. */
  114. void CL_ColorFlash (vec3_t pos, int ent, int intensity, float r, float g, float b)
  115. {
  116.     cdlight_t    *dl;
  117.  
  118.     dl = CL_AllocDlight (ent);
  119.     VectorCopy (pos,  dl->origin);
  120.     dl->radius = intensity;
  121.     dl->minlight = 250;
  122.     dl->die = cl.time + 100;
  123.     dl->color[0] = r;
  124.     dl->color[1] = g;
  125.     dl->color[2] = b;
  126. }
  127.  
  128.  
  129. /*
  130. ======
  131. CL_DebugTrail
  132. ======
  133. */
  134. void CL_DebugTrail (vec3_t start, vec3_t end)
  135. {
  136.     vec3_t        move;
  137.     vec3_t        vec;
  138.     float        len;
  139. //    int            j;
  140.     cparticle_t    *p;
  141.     float        dec;
  142.     vec3_t        right, up;
  143. //    int            i;
  144. //    float        d, c, s;
  145. //    vec3_t        dir;
  146.  
  147.     VectorCopy (start, move);
  148.     VectorSubtract (end, start, vec);
  149.     len = VectorNormalize (vec);
  150.  
  151.     MakeNormalVectors (vec, right, up);
  152.  
  153. //    VectorScale(vec, RT2_SKIP, vec);
  154.  
  155. //    dec = 1.0;
  156. //    dec = 0.75;
  157.     dec = 3;
  158.     VectorScale (vec, dec, vec);
  159.     VectorCopy (start, move);
  160.  
  161.     while (len > 0)
  162.     {
  163.         len -= dec;
  164.  
  165.         if (!(p = new_particle()))
  166.             return;
  167.  
  168.         VectorClear (p->accel);
  169.         VectorClear (p->vel);
  170.         p->alpha = 1.0;
  171.         p->alphavel = -0.1;
  172. //        p->alphavel = 0;
  173.         p->color = 0x74 + (rand()&7);
  174.         VectorCopy (move, p->org);
  175. /*
  176.         for (j=0 ; j<3 ; j++)
  177.         {
  178.             p->org[j] = move[j] + crand()*2;
  179.             p->vel[j] = crand()*3;
  180.             p->accel[j] = 0;
  181.         }
  182. */
  183.         VectorAdd (move, vec, move);
  184.     }
  185.  
  186. }
  187.  
  188. /*
  189. ===============
  190. CL_SmokeTrail
  191. ===============
  192. */
  193. void CL_SmokeTrail (vec3_t start, vec3_t end, int colorStart, int colorRun, int spacing)
  194. {
  195.     vec3_t        move;
  196.     vec3_t        vec;
  197.     float        len;
  198.     int            j;
  199.     cparticle_t    *p;
  200.  
  201.     VectorCopy (start, move);
  202.     VectorSubtract (end, start, vec);
  203.     len = VectorNormalize (vec);
  204.  
  205.     VectorScale (vec, spacing, vec);
  206.  
  207.     // FIXME: this is a really silly way to have a loop
  208.     while (len > 0)
  209.     {
  210.         len -= spacing;
  211.  
  212.         if (!(p = new_particle()))
  213.             return;
  214.         VectorClear (p->accel);
  215.         
  216.         p->alpha = 1.0;
  217.         p->alphavel = -1.0 / (1+frand()*0.5);
  218.         p->color = colorStart + (rand() % colorRun);
  219.         for (j=0 ; j<3 ; j++)
  220.         {
  221.             p->org[j] = move[j] + crand()*3;
  222.             p->accel[j] = 0;
  223.         }
  224.         p->vel[2] = 20 + crand()*5;
  225.  
  226.         VectorAdd (move, vec, move);
  227.     }
  228. }
  229.  
  230. void CL_ForceWall (vec3_t start, vec3_t end, int color)
  231. {
  232.     vec3_t        move;
  233.     vec3_t        vec;
  234.     float        len;
  235.     int            j;
  236.     cparticle_t    *p;
  237.  
  238.     VectorCopy (start, move);
  239.     VectorSubtract (end, start, vec);
  240.     len = VectorNormalize (vec);
  241.  
  242.     VectorScale (vec, 4, vec);
  243.  
  244.     // FIXME: this is a really silly way to have a loop
  245.     while (len > 0)
  246.     {
  247.         len -= 4;
  248.         
  249.         if (frand() > 0.3)
  250.         {
  251.             if (!(p = new_particle()))
  252.                 return;
  253.  
  254.             VectorClear (p->accel);
  255.  
  256.             p->alpha = 1.0;
  257.             p->alphavel =  -1.0 / (3.0+frand()*0.5);
  258.             p->color = color;
  259.             for (j=0 ; j<3 ; j++)
  260.             {
  261.                 p->org[j] = move[j] + crand()*3;
  262.                 p->accel[j] = 0;
  263.             }
  264.             p->vel[0] = 0;
  265.             p->vel[1] = 0;
  266.             p->vel[2] = -40 - (crand()*10);
  267.         }
  268.  
  269.         VectorAdd (move, vec, move);
  270.     }
  271. }
  272.  
  273. void CL_FlameEffects (centity_t *ent, vec3_t origin)
  274. {
  275.     int            n, count;
  276.     int            j;
  277.     cparticle_t    *p;
  278.  
  279.     count = rand() & 0xF;
  280.  
  281.     for(n=0;n<count;n++)
  282.     {
  283.         if (!(p = new_particle()))
  284.             return;
  285.         
  286.         VectorClear (p->accel);
  287.  
  288.         p->alpha = 1.0;
  289.         p->alphavel = -1.0 / (1+frand()*0.2);
  290.         p->color = 226 + (rand() % 4);
  291.         for (j=0 ; j<3 ; j++)
  292.         {
  293.             p->org[j] = origin[j] + crand()*5;
  294.             p->vel[j] = crand()*5;
  295.         }
  296.         p->vel[2] = crand() * -10;
  297.         p->accel[2] = -PARTICLE_GRAVITY;
  298.     }
  299.  
  300.     count = rand() & 0x7;
  301.  
  302.     for(n=0;n<count;n++)
  303.     {
  304.         if (!(p = new_particle()))
  305.             return;
  306.  
  307.         VectorClear (p->accel);
  308.  
  309.         p->alpha = 1.0;
  310.         p->alphavel = -1.0 / (1+frand()*0.5);
  311.         p->color = 0 + (rand() % 4);
  312.         for (j=0 ; j<3 ; j++)
  313.         {
  314.             p->org[j] = origin[j] + crand()*3;
  315.         }
  316.         p->vel[2] = 20 + crand()*5;
  317.     }
  318.  
  319. }
  320.  
  321.  
  322. /*
  323. ===============
  324. CL_GenericParticleEffect
  325. ===============
  326. */
  327. void CL_GenericParticleEffect (vec3_t org, vec3_t dir, int color, int count, int numcolors, int dirspread, float alphavel)
  328. {
  329.     int            i, j;
  330.     cparticle_t    *p;
  331.     float        d;
  332.  
  333.     for (i=0 ; i<count ; i++)
  334.     {
  335.         if (!(p = new_particle()))
  336.             return;
  337.  
  338.         if (numcolors > 1)
  339.             p->color = color + (rand() & numcolors);
  340.         else
  341.             p->color = color;
  342.  
  343.         d = rand() & dirspread;
  344.         for (j=0 ; j<3 ; j++)
  345.         {
  346.             p->org[j] = org[j] + ((rand()&7)-4) + d*dir[j];
  347.             p->vel[j] = crand()*20;
  348.         }
  349.  
  350.         p->accel[0] = p->accel[1] = 0;
  351.         p->accel[2] = -PARTICLE_GRAVITY;
  352. //        VectorCopy (accel, p->accel);
  353.         p->alpha = 1.0;
  354.  
  355.         p->alphavel = -1.0 / (0.5 + frand()*alphavel);
  356. //        p->alphavel = alphavel;
  357.     }
  358. }
  359.  
  360. /*
  361. ===============
  362. CL_BubbleTrail2 (lets you control the # of bubbles by setting the distance between the spawns)
  363.  
  364. ===============
  365. */
  366. void CL_BubbleTrail2 (vec3_t start, vec3_t end, int dist)
  367. {
  368.     vec3_t        move;
  369.     vec3_t        vec;
  370.     float        len;
  371.     int            i, j;
  372.     cparticle_t    *p;
  373.     float        dec;
  374.  
  375.     VectorCopy (start, move);
  376.     VectorSubtract (end, start, vec);
  377.     len = VectorNormalize (vec);
  378.  
  379.     dec = dist;
  380.     VectorScale (vec, dec, vec);
  381.  
  382.     for (i=0 ; i<len ; i+=dec)
  383.     {
  384.         if (!(p = new_particle()))
  385.             return;
  386.  
  387.         VectorClear (p->accel);
  388.  
  389.         p->alpha = 1.0;
  390.         p->alphavel = -1.0 / (1+frand()*0.1);
  391.         p->color = 4 + (rand()&7);
  392.         for (j=0 ; j<3 ; j++)
  393.         {
  394.             p->org[j] = move[j] + crand()*2;
  395.             p->vel[j] = crand()*10;
  396.         }
  397.         p->org[2] -= 4;
  398. //        p->vel[2] += 6;
  399.         p->vel[2] += 20;
  400.  
  401.         VectorAdd (move, vec, move);
  402.     }
  403. }
  404.  
  405. //#define CORKSCREW        1
  406. //#define DOUBLE_SCREW    1
  407. #define    RINGS        1
  408. //#define    SPRAY        1
  409.  
  410. #ifdef CORKSCREW
  411. void CL_Heatbeam (vec3_t start, vec3_t end)
  412. {
  413.     vec3_t        move;
  414.     vec3_t        vec;
  415.     float        len;
  416.     int            j,k;
  417.     cparticle_t    *p;
  418.     vec3_t        right, up;
  419.     int            i;
  420.     float        d, c, s;
  421.     vec3_t        dir;
  422.     float        ltime;
  423.     float        step = 5.0;
  424.  
  425.     VectorCopy (start, move);
  426.     VectorSubtract (end, start, vec);
  427.     len = VectorNormalize (vec);
  428.  
  429. //    MakeNormalVectors (vec, right, up);
  430.     VectorCopy (cl.v_right, right);
  431.     VectorCopy (cl.v_up, up);
  432.     VectorMA (move, -1, right, move);
  433.     VectorMA (move, -1, up, move);
  434.  
  435.     VectorScale (vec, step, vec);
  436.     ltime = (float) cl.time/1000.0;
  437.  
  438. //    for (i=0 ; i<len ; i++)
  439.     for (i=0 ; i<len ; i+=step)
  440.     {
  441.         d = i * 0.1 - fmod(ltime,16.0)*M_PI;
  442.         c = cos(d)/1.75;
  443.         s = sin(d)/1.75;
  444. #ifdef DOUBLE_SCREW        
  445.         for (k=-1; k<2; k+=2)
  446.         {
  447. #else
  448.         k=1;
  449. #endif
  450.         if (!(p = new_particle()))
  451.             return;
  452.             
  453.             VectorClear (p->accel);
  454.  
  455.             p->alpha = 0.5;
  456.     //        p->alphavel = -1.0 / (1+frand()*0.2);
  457.             // only last one frame!
  458.             p->alphavel = INSTANT_PARTICLE;
  459.     //        p->color = 0x74 + (rand()&7);
  460. //            p->color = 223 - (rand()&7);
  461.             p->ptype = PARTICLE_HEATBEAM;
  462. //            p->color = 240;
  463.  
  464.             // trim it so it looks like it's starting at the origin
  465.             if (i < 10)
  466.             {
  467.                 VectorScale (right, c*(i/10.0)*k, dir);
  468.                 VectorMA (dir, s*(i/10.0)*k, up, dir);
  469.             }
  470.             else
  471.             {
  472.                 VectorScale (right, c*k, dir);
  473.                 VectorMA (dir, s*k, up, dir);
  474.             }
  475.             
  476.             for (j=0 ; j<3 ; j++)
  477.             {
  478.                 p->org[j] = move[j] + dir[j]*3;
  479.     //            p->vel[j] = dir[j]*6;
  480.                 p->vel[j] = 0;
  481.             }
  482. #ifdef DOUBLE_SCREW
  483.         }
  484. #endif
  485.         VectorAdd (move, vec, move);
  486.     }
  487. }
  488. #endif
  489. #ifdef RINGS
  490. //void CL_Heatbeam (vec3_t start, vec3_t end)
  491. void CL_Heatbeam (vec3_t start, vec3_t end)
  492. {
  493.     vec3_t        move;
  494.     vec3_t        vec;
  495.     float        len;
  496.     int            j;
  497.     cparticle_t    *p;
  498.     vec3_t        right, up;
  499.     int            i;
  500.     float        c, s;
  501.     vec3_t        dir;
  502.     float        ltime;
  503.     float        step = 44.0, rstep;
  504.     float        start_pt;
  505.     float        rot;
  506.     float        variance;
  507.     //vec3_t        end;
  508.  
  509.     //VectorMA (start, 4096, forward, end);
  510.  
  511.     VectorCopy (start, move);
  512.     VectorSubtract (end, start, vec);
  513.     len = VectorNormalize (vec);
  514.  
  515.     // FIXME - pmm - these might end up using old values?
  516. //    MakeNormalVectors (vec, right, up);
  517.     VectorCopy (cl.v_right, right);
  518.     VectorCopy (cl.v_up, up);
  519.     VectorMA (move, -0.5, right, move);
  520.     VectorMA (move, -0.5, up, move);
  521.  
  522.     ltime = (float) cl.time/1000.0;
  523.     start_pt = fmod(ltime*96.0,step);
  524.     VectorMA (move, start_pt, vec, move);
  525.  
  526.     VectorScale (vec, step, vec);
  527.  
  528. //    Com_Printf ("%f\n", ltime);
  529.     rstep = M_PI/60.0;
  530.     for (i=start_pt ; i<len ; i+=step)
  531.     {
  532.         //if (i>step*5) // don't bother after the 5th ring
  533.         //    break;
  534.  
  535.         for (rot = 0; rot < M_PI*2; rot += rstep)
  536.         {
  537.             if (!(p = new_particle()))
  538.                 return;
  539.             
  540.             VectorClear (p->accel);
  541. //            rot+= fmod(ltime, 12.0)*M_PI;
  542. //            c = cos(rot)/2.0;
  543. //            s = sin(rot)/2.0;
  544. //            variance = 0.4 + ((float)rand()/(float)RAND_MAX) *0.2;
  545.             variance = 50.0;
  546.             c = cos(rot)*20;
  547.             s = sin(rot)*5;
  548.             
  549.             // trim it so it looks like it's starting at the origin
  550.             if (i < 40)
  551.             {
  552.                 VectorScale (right, c*(i/10.0), dir);
  553.                 VectorMA (dir, s*(i/10.0), up, dir);
  554.             }
  555.             else
  556.             {
  557.                 VectorScale (right, c, dir);
  558.                 VectorMA (dir, s, up, dir);
  559.             }
  560.         
  561.             p->alpha = 0.5;
  562.             p->alphavel = -1.0 / (1+frand()*0.2);
  563.             //p->alphavel = -1000.0;
  564.     //        p->color = 0x74 + (rand()&7);
  565.             p->color = 223 - (rand()&7);
  566.             p->type = PARTICLE_GREEN_LASER1;
  567.             for (j=0 ; j<3 ; j++)
  568.             {
  569.                 p->org[j] = move[j] + dir[j]*3;
  570.     //            p->vel[j] = dir[j]*6;
  571.                 p->vel[j] = 0;
  572.             }
  573.         }
  574.         VectorAdd (move, vec, move);
  575.     }
  576. }
  577. #endif
  578. #ifdef SPRAY
  579. void CL_Heatbeam (vec3_t start, vec3_t end)
  580. {
  581.     vec3_t        move;
  582.     vec3_t        vec;
  583.     float        len;
  584.     int            j;
  585.     cparticle_t    *p;
  586.     vec3_t        forward, right, up;
  587.     int            i;
  588.     float        d, c, s;
  589.     vec3_t        dir;
  590.     float        ltime;
  591.     float        step = 32.0, rstep;
  592.     float        start_pt;
  593.     float        rot;
  594.  
  595.     VectorCopy (start, move);
  596.     VectorSubtract (end, start, vec);
  597.     len = VectorNormalize (vec);
  598.  
  599. //    MakeNormalVectors (vec, right, up);
  600.     VectorCopy (cl.v_forward, forward);
  601.     VectorCopy (cl.v_right, right);
  602.     VectorCopy (cl.v_up, up);
  603.     VectorMA (move, -0.5, right, move);
  604.     VectorMA (move, -0.5, up, move);
  605.  
  606.     for (i=0; i<8; i++)
  607.     {
  608.         if (!(p = new_particle()))
  609.             return;
  610.         
  611.         VectorClear (p->accel);
  612.         
  613.         d = crand()*M_PI;
  614.         c = cos(d)*30;
  615.         s = sin(d)*30;
  616.  
  617.         p->alpha = 1.0;
  618.         p->alphavel = -5.0 / (1+frand());
  619.         p->color = 223 - (rand()&7);
  620.  
  621.         for (j=0 ; j<3 ; j++)
  622.         {
  623.             p->org[j] = move[j];
  624.         }
  625.         VectorScale (vec, 450, p->vel);
  626.         VectorMA (p->vel, c, right, p->vel);
  627.         VectorMA (p->vel, s, up, p->vel);
  628.     }
  629. /*
  630.  
  631.     ltime = (float) cl.time/1000.0;
  632.     start_pt = fmod(ltime*16.0,step);
  633.     VectorMA (move, start_pt, vec, move);
  634.  
  635.     VectorScale (vec, step, vec);
  636.  
  637. //    Com_Printf ("%f\n", ltime);
  638.     rstep = M_PI/12.0;
  639.     for (i=start_pt ; i<len ; i+=step)
  640.     {
  641.         if (i>step*5) // don't bother after the 5th ring
  642.             break;
  643.  
  644.         for (rot = 0; rot < M_PI*2; rot += rstep)
  645.         {
  646.             if (!(p = new_particle()))
  647.                 return;
  648.             
  649.             VectorClear (p->accel);
  650. //            rot+= fmod(ltime, 12.0)*M_PI;
  651. //            c = cos(rot)/2.0;
  652. //            s = sin(rot)/2.0;
  653.             c = cos(rot)/1.5;
  654.             s = sin(rot)/1.5;
  655.             
  656.             // trim it so it looks like it's starting at the origin
  657.             if (i < 10)
  658.             {
  659.                 VectorScale (right, c*(i/10.0), dir);
  660.                 VectorMA (dir, s*(i/10.0), up, dir);
  661.             }
  662.             else
  663.             {
  664.                 VectorScale (right, c, dir);
  665.                 VectorMA (dir, s, up, dir);
  666.             }
  667.         
  668.             p->alpha = 0.5;
  669.     //        p->alphavel = -1.0 / (1+frand()*0.2);
  670.             p->alphavel = -1000.0;
  671.     //        p->color = 0x74 + (rand()&7);
  672.             p->color = 223 - (rand()&7);
  673.             for (j=0 ; j<3 ; j++)
  674.             {
  675.                 p->org[j] = move[j] + dir[j]*3;
  676.     //            p->vel[j] = dir[j]*6;
  677.                 p->vel[j] = 0;
  678.             }
  679.         }
  680.         VectorAdd (move, vec, move);
  681.     }
  682. */
  683. }
  684. #endif
  685.  
  686. /*
  687. ===============
  688. CL_ParticleSteamEffect
  689.  
  690. Puffs with velocity along direction, with some randomness thrown in
  691. ===============
  692. */
  693. void CL_ParticleSteamEffect (vec3_t org, vec3_t dir, int color, int count, int magnitude)
  694. {
  695.     int            i, j;
  696.     cparticle_t    *p;
  697.     float        d;
  698.     vec3_t        r, u;
  699.  
  700. //    vectoangles2 (dir, angle_dir);
  701. //    AngleVectors (angle_dir, f, r, u);
  702.  
  703.     MakeNormalVectors (dir, r, u);
  704.  
  705.     for (i=0 ; i<count ; i++)
  706.     {
  707.         if (!(p = new_particle()))
  708.             return;
  709.  
  710.         p->color = color + (rand()&7);
  711.  
  712.         for (j=0 ; j<3 ; j++)
  713.         {
  714.             p->org[j] = org[j] + magnitude*0.1*crand();
  715. //            p->vel[j] = dir[j]*magnitude;
  716.         }
  717.         VectorScale (dir, magnitude, p->vel);
  718.         d = crand()*magnitude/3;
  719.         VectorMA (p->vel, d, r, p->vel);
  720.         d = crand()*magnitude/3;
  721.         VectorMA (p->vel, d, u, p->vel);
  722.  
  723.         p->accel[0] = p->accel[1] = 0;
  724.         p->accel[2] = -PARTICLE_GRAVITY/2;
  725.         p->alpha = 1.0;
  726.  
  727.         p->alphavel = -1.0 / (0.5 + frand()*0.3);
  728.     }
  729. }
  730.  
  731. void CL_ParticleSteamEffect2 (cl_sustain_t *self)
  732. //vec3_t org, vec3_t dir, int color, int count, int magnitude)
  733. {
  734.     int            i, j;
  735.     cparticle_t    *p;
  736.     float        d;
  737.     vec3_t        r, u;
  738.     vec3_t        dir;
  739.  
  740. //    vectoangles2 (dir, angle_dir);
  741. //    AngleVectors (angle_dir, f, r, u);
  742.  
  743.     VectorCopy (self->dir, dir);
  744.     MakeNormalVectors (dir, r, u);
  745.  
  746.     for (i=0 ; i<self->count ; i++)
  747.     {
  748.         if (!(p = new_particle()))
  749.             return;
  750.  
  751.         p->type = PARTICLE_STEAM;//self->color + (rand()&7);
  752.  
  753.         for (j=0 ; j<3 ; j++)
  754.         {
  755.             p->org[j] = self->org[j] + self->magnitude*0.1*crand();
  756. //            p->vel[j] = dir[j]*magnitude;
  757.         }
  758.         VectorScale (dir, self->magnitude, p->vel);
  759.         d = crand()*self->magnitude/3;
  760.         VectorMA (p->vel, d, r, p->vel);
  761.         d = crand()*self->magnitude/3;
  762.         VectorMA (p->vel, d, u, p->vel);
  763.  
  764.         p->accel[0] = p->accel[1] = 0;
  765.         p->accel[2] = -PARTICLE_GRAVITY/2;
  766.         p->alpha = 0.7;
  767.  
  768.         p->alphavel = -1.0 / (0.5 + frand()*0.3);
  769.     }
  770.     self->nextthink += self->thinkinterval;
  771. }
  772. void CL_ParticleFireEffect2 (cl_sustain_t *self)
  773. //vec3_t org, vec3_t dir, int color, int count, int magnitude)
  774. {
  775.     int            i, j;
  776.     cparticle_t    *p;
  777.     float        d;
  778.     vec3_t        r, u;
  779.     vec3_t        dir;
  780.  
  781. //    vectoangles2 (dir, angle_dir);
  782. //    AngleVectors (angle_dir, f, r, u);
  783.  
  784.     VectorCopy (self->dir, dir);
  785.     MakeNormalVectors (dir, r, u);
  786.  
  787.     for (i=0 ; i<self->count ; i++)
  788.     {
  789.         if (!(p = new_particle()))
  790.             return;
  791.  
  792.         p->type = PARTICLE_EXPLOSION;//self->color + (rand()&7);
  793.  
  794.         for (j=0 ; j<3 ; j++)
  795.         {
  796.             p->org[j] = self->org[j] + self->magnitude*0.1*crand();
  797. //            p->vel[j] = dir[j]*magnitude;
  798.         }
  799.         VectorScale (dir, self->magnitude, p->vel);
  800.         d = crand()*self->magnitude/3;
  801.         VectorMA (p->vel, d, r, p->vel);
  802.         d = crand()*self->magnitude/3;
  803.         VectorMA (p->vel, d, u, p->vel);
  804.  
  805.         p->accel[0] = p->accel[1] = 0;
  806.         p->accel[2] = -PARTICLE_GRAVITY/2;
  807.         p->alpha = 0.7;
  808.  
  809.         p->alphavel = -1.0 / (0.5 + frand()*0.3);
  810.     }
  811.     self->nextthink += self->thinkinterval;
  812. }
  813. void CL_ParticleSmokeEffect2 (cl_sustain_t *self)
  814. //vec3_t org, vec3_t dir, int color, int count, int magnitude)
  815. {
  816.     int            i, j;
  817.     cparticle_t    *p;
  818.     float        d;
  819.     vec3_t        r, u;
  820.     vec3_t        dir;
  821.  
  822. //    vectoangles2 (dir, angle_dir);
  823. //    AngleVectors (angle_dir, f, r, u);
  824.  
  825.     VectorCopy (self->dir, dir);
  826.     MakeNormalVectors (dir, r, u);
  827.  
  828.     for (i=0 ; i<self->count ; i++)
  829.     {
  830.         if (!(p = new_particle()))
  831.             return;
  832.  
  833.         p->type = PARTICLE_SMOKE2;//self->color + (rand()&7);
  834.  
  835.         for (j=0 ; j<3 ; j++)
  836.         {
  837.             p->org[j] = self->org[j] + self->magnitude*0.1*crand();
  838. //            p->vel[j] = dir[j]*magnitude;
  839.         }
  840.         VectorScale (dir, self->magnitude, p->vel);
  841.         d = crand()*self->magnitude/3;
  842.         VectorMA (p->vel, d, r, p->vel);
  843.         d = crand()*self->magnitude/3;
  844.         VectorMA (p->vel, d, u, p->vel);
  845.  
  846.         p->accel[0] = p->accel[1] = 0;
  847.         p->accel[2] = -PARTICLE_GRAVITY/2;
  848.         p->alpha = 0.2;
  849.  
  850.         p->alphavel = -1.0 / (1.8 + frand()*0.3);
  851.     }
  852.     self->nextthink += self->thinkinterval;
  853. }
  854. /*
  855. ===============
  856. CL_TrackerTrail
  857. ===============
  858. */
  859. void CL_TrackerTrail (vec3_t start, vec3_t end, int particleColor)
  860. {
  861.     vec3_t        move;
  862.     vec3_t        vec;
  863.     vec3_t        forward,right,up,angle_dir;
  864.     float        len;
  865.     int            j;
  866.     cparticle_t    *p;
  867.     int            dec;
  868.     float        dist;
  869.  
  870.     VectorCopy (start, move);
  871.     VectorSubtract (end, start, vec);
  872.     len = VectorNormalize (vec);
  873.  
  874.     VectorCopy(vec, forward);
  875.     vectoangles2 (forward, angle_dir);
  876.     AngleVectors (angle_dir, forward, right, up);
  877.  
  878.     dec = 3;
  879.     VectorScale (vec, 3, vec);
  880.  
  881.     // FIXME: this is a really silly way to have a loop
  882.     while (len > 0)
  883.     {
  884.         len -= dec;
  885.  
  886.         if (!(p = new_particle()))
  887.             return;
  888.         VectorClear (p->accel);
  889.         
  890.         p->alpha = 1.0;
  891.         p->alphavel = -2.0;
  892.         p->color = particleColor;
  893.         dist = DotProduct(move, forward);
  894.         VectorMA(move, 8 * cos(dist), up, p->org);
  895.         for (j=0 ; j<3 ; j++)
  896.         {
  897. //            p->org[j] = move[j] + crand();
  898.             p->vel[j] = 0;
  899.             p->accel[j] = 0;
  900.         }
  901.         p->vel[2] = 5;
  902.  
  903.         VectorAdd (move, vec, move);
  904.     }
  905. }
  906.  
  907. void CL_Tracker_Shell(vec3_t origin)
  908. {
  909.     vec3_t            dir;
  910.     int                i;
  911.     cparticle_t        *p;
  912.  
  913.     for(i=0;i<300;i++)
  914.     {
  915.         if (!(p = new_particle()))
  916.             return;
  917.         VectorClear (p->accel);
  918.         
  919.         p->alpha = 1.0;
  920.         p->alphavel = INSTANT_PARTICLE;
  921.         p->color = 0;
  922.  
  923.         dir[0] = crand();
  924.         dir[1] = crand();
  925.         dir[2] = crand();
  926.         VectorNormalize(dir);
  927.     
  928.         VectorMA(origin, 40, dir, p->org);
  929.     }
  930. }
  931.  
  932. void CL_MonsterPlasma_Shell(vec3_t origin)
  933. {
  934.     vec3_t            dir;
  935.     int                i;
  936.     cparticle_t        *p;
  937.  
  938.     for(i=0;i<40;i++)
  939.     {
  940.         if (!(p = new_particle()))
  941.             return;
  942.         VectorClear (p->accel);
  943.  
  944.         p->alpha = 1.0;
  945.         p->alphavel = INSTANT_PARTICLE;
  946.         p->color = 0xe0;
  947.  
  948.         dir[0] = crand();
  949.         dir[1] = crand();
  950.         dir[2] = crand();
  951.         VectorNormalize(dir);
  952.     
  953.         VectorMA(origin, 10, dir, p->org);
  954. //        VectorMA(origin, 10*(((rand () & 0x7fff) / ((float)0x7fff))), dir, p->org);
  955.     }
  956. }
  957.  
  958. void CL_Widowbeamout (cl_sustain_t *self)
  959. {
  960.     vec3_t            dir;
  961.     int                i;
  962.     cparticle_t        *p;
  963.     static int colortable[4] = {2*8,13*8,21*8,18*8};
  964.     float            ratio;
  965.  
  966.     ratio = 1.0 - (((float)self->endtime - (float)cl.time)/2100.0);
  967.  
  968.     for(i=0;i<300;i++)
  969.     {
  970.         if (!(p = new_particle()))
  971.             return;
  972.         VectorClear (p->accel);
  973.  
  974.         p->alpha = 1.0;
  975.         p->alphavel = INSTANT_PARTICLE;
  976.         p->color = colortable[rand()&3];
  977.  
  978.         dir[0] = crand();
  979.         dir[1] = crand();
  980.         dir[2] = crand();
  981.         VectorNormalize(dir);
  982.     
  983.         VectorMA(self->org, (45.0 * ratio), dir, p->org);
  984. //        VectorMA(origin, 10*(((rand () & 0x7fff) / ((float)0x7fff))), dir, p->org);
  985.     }
  986. }
  987.  
  988. void CL_Nukeblast (cl_sustain_t *self)
  989. {
  990.     vec3_t            dir;
  991.     int                i;
  992.     cparticle_t        *p;
  993.     static int colortable[4] = {110, 112, 114, 116};
  994.     float            ratio;
  995.  
  996.     ratio = 1.0 - (((float)self->endtime - (float)cl.time)/1000.0);
  997.  
  998.     for(i=0;i<700;i++)
  999.     {
  1000.         if (!(p = new_particle()))
  1001.             return;
  1002.         VectorClear (p->accel);
  1003.  
  1004.         p->alpha = 1.0;
  1005.         p->alphavel = INSTANT_PARTICLE;
  1006.         p->color = colortable[rand()&3];
  1007.  
  1008.         dir[0] = crand();
  1009.         dir[1] = crand();
  1010.         dir[2] = crand();
  1011.         VectorNormalize(dir);
  1012.     
  1013.         VectorMA(self->org, (200.0 * ratio), dir, p->org);
  1014. //        VectorMA(origin, 10*(((rand () & 0x7fff) / ((float)0x7fff))), dir, p->org);
  1015.     }
  1016. }
  1017.  
  1018. void CL_WidowSplash (vec3_t org)
  1019. {
  1020.     static int colortable[4] = {2*8,13*8,21*8,18*8};
  1021.     int            i;
  1022.     cparticle_t    *p;
  1023.     vec3_t        dir;
  1024.  
  1025.     for (i=0 ; i<256 ; i++)
  1026.     {
  1027.         if (!(p = new_particle()))
  1028.             return;
  1029.  
  1030.         p->color = colortable[rand()&3];
  1031.  
  1032.         dir[0] = crand();
  1033.         dir[1] = crand();
  1034.         dir[2] = crand();
  1035.         VectorNormalize(dir);
  1036.         VectorMA(org, 45.0, dir, p->org);
  1037.         VectorMA(vec3_origin, 40.0, dir, p->vel);
  1038.  
  1039.         p->accel[0] = p->accel[1] = 0;
  1040.         p->alpha = 1.0;
  1041.  
  1042.         p->alphavel = -0.8 / (0.5 + frand()*0.3);
  1043.     }
  1044.  
  1045. }
  1046.  
  1047. void CL_Tracker_Explode(vec3_t    origin)
  1048. {
  1049.     vec3_t            dir, backdir;
  1050.     int                i;
  1051.     cparticle_t        *p;
  1052.  
  1053.     for(i=0;i<300;i++)
  1054.     {
  1055.         if (!(p = new_particle()))
  1056.             return;
  1057.         VectorClear (p->accel);
  1058.  
  1059.         p->alpha = 1.0;
  1060.         p->alphavel = -1.0;
  1061.         p->color = 0;
  1062.  
  1063.         dir[0] = crand();
  1064.         dir[1] = crand();
  1065.         dir[2] = crand();
  1066.         VectorNormalize(dir);
  1067.         VectorScale(dir, -1, backdir);
  1068.     
  1069.         VectorMA(origin, 64, dir, p->org);
  1070.         VectorScale(backdir, 64, p->vel);
  1071.     }
  1072.     
  1073. }
  1074.  
  1075. /*
  1076. ===============
  1077. CL_TagTrail
  1078.  
  1079. ===============
  1080. */
  1081. void CL_TagTrail (vec3_t start, vec3_t end, float color)
  1082. {
  1083.     vec3_t        move;
  1084.     vec3_t        vec;
  1085.     float        len;
  1086.     int            j;
  1087.     cparticle_t    *p;
  1088.     int            dec;
  1089.  
  1090.     VectorCopy (start, move);
  1091.     VectorSubtract (end, start, vec);
  1092.     len = VectorNormalize (vec);
  1093.  
  1094.     dec = 5;
  1095.     VectorScale (vec, 5, vec);
  1096.  
  1097.     while (len >= 0)
  1098.     {
  1099.         len -= dec;
  1100.  
  1101.         if (!(p = new_particle()))
  1102.             return;
  1103.         VectorClear (p->accel);
  1104.  
  1105.         p->alpha = 1.0;
  1106.         p->alphavel = -1.0 / (0.8+frand()*0.2);
  1107.         p->color = color;
  1108.         for (j=0 ; j<3 ; j++)
  1109.         {
  1110.             p->org[j] = move[j] + crand()*16;
  1111.             p->vel[j] = crand()*5;
  1112.             p->accel[j] = 0;
  1113.         }
  1114.  
  1115.         VectorAdd (move, vec, move);
  1116.     }
  1117. }
  1118.  
  1119. /*
  1120. ===============
  1121. CL_ColorExplosionParticles
  1122. ===============
  1123. */
  1124. void CL_ColorExplosionParticles (vec3_t org, int color, int run)
  1125. {
  1126.     int            i, j;
  1127.     cparticle_t    *p;
  1128.  
  1129.     for (i=0 ; i<128 ; i++)
  1130.     {
  1131.         if (!(p = new_particle()))
  1132.             return;
  1133.  
  1134.         p->color = color + (rand() % run);
  1135.  
  1136.         for (j=0 ; j<3 ; j++)
  1137.         {
  1138.             p->org[j] = org[j] + ((rand()%32)-16);
  1139.             p->vel[j] = (rand()%256)-128;
  1140.         }
  1141.  
  1142.         p->accel[0] = p->accel[1] = 0;
  1143.         p->accel[2] = -PARTICLE_GRAVITY;
  1144.         p->alpha = 1.0;
  1145.  
  1146.         p->alphavel = -0.4 / (0.6 + frand()*0.2);
  1147.     }
  1148. }
  1149.  
  1150. /*
  1151. ===============
  1152. CL_ParticleSmokeEffect - like the steam effect, but unaffected by gravity
  1153. ===============
  1154. */
  1155. void CL_ParticleSmokeEffect (vec3_t org, vec3_t dir, int color, int count, int magnitude)
  1156. {
  1157.     int            i, j;
  1158.     cparticle_t    *p;
  1159.     float        d;
  1160.     vec3_t        r, u;
  1161.  
  1162.     MakeNormalVectors (dir, r, u);
  1163.  
  1164.     for (i=0 ; i<count ; i++)
  1165.     {
  1166.         if (!(p = new_particle()))
  1167.             return;
  1168.  
  1169.         p->color = color + (rand()&7);
  1170.  
  1171.         for (j=0 ; j<3 ; j++)
  1172.         {
  1173.             p->org[j] = org[j] + magnitude*0.1*crand();
  1174. //            p->vel[j] = dir[j]*magnitude;
  1175.         }
  1176.         VectorScale (dir, magnitude, p->vel);
  1177.         d = crand()*magnitude/3;
  1178.         VectorMA (p->vel, d, r, p->vel);
  1179.         d = crand()*magnitude/3;
  1180.         VectorMA (p->vel, d, u, p->vel);
  1181.  
  1182.         p->accel[0] = p->accel[1] = p->accel[2] = 0;
  1183.         p->alpha = 1.0;
  1184.         p->alphavel = -1.0 / (0.5 + frand()*0.3);
  1185.     }
  1186. }
  1187.  
  1188. /*
  1189. ===============
  1190. CL_BlasterParticles2
  1191.  
  1192. Wall impact puffs (Green)
  1193. ===============
  1194. */
  1195. void CL_BlasterParticles2 (vec3_t org, vec3_t dir, unsigned int color)
  1196. {
  1197.     int            i, j;
  1198.     cparticle_t    *p;
  1199.     float        d;
  1200.     int            count;
  1201.  
  1202.     count = 40;
  1203.     for (i=0 ; i<count ; i++)
  1204.     {
  1205.         if (!(p = new_particle()))
  1206.             return;
  1207.  
  1208.         p->color = color + (rand()&7);
  1209.  
  1210.         d = rand()&15;
  1211.         for (j=0 ; j<3 ; j++)
  1212.         {
  1213.             p->org[j] = org[j] + ((rand()&7)-4) + d*dir[j];
  1214.             p->vel[j] = dir[j] * 30 + crand()*40;
  1215.         }
  1216.  
  1217.         p->accel[0] = p->accel[1] = 0;
  1218.         p->accel[2] = -PARTICLE_GRAVITY;
  1219.         p->alpha = 1.0;
  1220.  
  1221.         p->alphavel = -1.0 / (0.5 + frand()*0.3);
  1222.     }
  1223. }
  1224.  
  1225. /*
  1226. ===============
  1227. CL_BlasterTrail2
  1228.  
  1229. Green!
  1230. ===============
  1231. */
  1232. void CL_BlasterTrail2 (vec3_t start, vec3_t end)
  1233. {
  1234.     vec3_t        move;
  1235.     vec3_t        vec;
  1236.     float        len;
  1237.     int            j;
  1238.     cparticle_t    *p;
  1239.     int            dec;
  1240.  
  1241.     VectorCopy (start, move);
  1242.     VectorSubtract (end, start, vec);
  1243.     len = VectorNormalize (vec);
  1244.  
  1245.     dec = 5;
  1246.     VectorScale (vec, 5, vec);
  1247.  
  1248.     // FIXME: this is a really silly way to have a loop
  1249.     while (len > 0)
  1250.     {
  1251.         len -= dec;
  1252.  
  1253.         if (!(p = new_particle()))
  1254.             return;
  1255.         VectorClear (p->accel);
  1256.  
  1257.         p->alpha = 1.0;
  1258.         p->alphavel = -1.0 / (0.3+frand()*0.2);
  1259.         p->color = 0xd0;
  1260.         for (j=0 ; j<3 ; j++)
  1261.         {
  1262.             p->org[j] = move[j] + crand();
  1263.             p->vel[j] = crand()*5;
  1264.             p->accel[j] = 0;
  1265.         }
  1266.  
  1267.         VectorAdd (move, vec, move);
  1268.     }
  1269. }
  1270.